package com.brsya.aliplayview;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.aliyun.player.AliPlayer;
import com.aliyun.player.AliPlayerFactory;
import com.aliyun.player.IPlayer;
import com.aliyun.player.bean.ErrorInfo;
import com.aliyun.player.bean.InfoBean;
import com.aliyun.player.bean.InfoCode;
import com.aliyun.player.source.UrlSource;

import java.util.Locale;

/**
 * Created by Brsya
 * CreateDate: 2022/5/24  15:04
 * Description:
 * 阿里云播放器View
 */
public class PlayLayout extends RelativeLayout {

    private static final String TAG = "brsya_play_layout:";
    private AliPlayer aliPlayer;

    private PlayListener playListener;

    private String videoUrl;
    private SurfaceView svPlay;
    private TextView tvTime;
    private LinearLayout llLightBox;
    private ProgressBar pbLight;
    private TextView tvLight;
    private LinearLayout llVoiceBox;
    private ProgressBar pbVoice;
    private TextView tvVoice;

    /**
     * 设置初始播放时间
     */
    private long playTimeStart = -1;
    /**
     * 播放时间
     */
    private long playTime = -1;
    /**
     * View 宽度
     */
    private int width;
    /**
     * View 高度
     */
    private int height;
    /**
     * 最大进度
     */
    private long maxProgressValue;

    /**
     * 每像素对应播放进度
     */
    private long pxProgressValue;

    /**
     * 上次操作位置
     */
    private float touchX;
    private float touchY;
    /**
     * 按下时播放时间
     */
    private long playTimeDown = -1;

    /**
     * 需要跳转到的播放位置
     */
    private long seekToNow = 0;

    private AudioManager mAudioManager;
    /**
     * 最大音量
     */
    private int voiceMax;
    /**
     * 最小音量
     * 9.0后可获取
     */
    private int voiceMin = 0;
    /**
     * 按下时音量
     */
    private int VoiceCurrentDown;
    /**
     * 是否横向滚动
     */
    private boolean isHorizontal;
    /**
     * 是否纵向滚动
     */
    private boolean isVertical;

    /**
     * 用于改变window级屏幕亮度
     * 不会改变系统亮度
     * 不影响其他页面
     */
    private Window window;
    /**
     * 按下时亮度
     */
    private float brightnessDown;

    /**
     * 是否不可操作
     */
    private boolean isLock = false;

    private boolean isTouch = false;

    public PlayLayout(Context context) {
        super(context);
        init();
    }

    public PlayLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PlayLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    private void initView() {
        svPlay = findViewById(R.id.sv_play);
        tvTime = findViewById(R.id.tv_time);
        llLightBox = findViewById(R.id.ll_light_box);
        pbLight = findViewById(R.id.pb_light);
        tvLight = findViewById(R.id.tv_light);
        llVoiceBox = findViewById(R.id.ll_voice_box);
        pbVoice = findViewById(R.id.pb_voice);
        tvVoice = findViewById(R.id.tv_voice);
    }


    private void init() {
        View root = LayoutInflater.from(getContext()).inflate(R.layout.view_play, this, false);
        addView(root);
        initView();


        aliPlayer = AliPlayerFactory.createAliPlayer(getContext());
        aliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
            @Override
            public void onPrepared() {
                if (playListener != null) {
                    playListener.onPrepared();
                }
                maxProgressValue = aliPlayer.getDuration();
                pxProgressValue = maxProgressValue / width;
                if (pxProgressValue < 1) {
                    pxProgressValue = 1;
                }
            }
        });
        aliPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
            @Override
            public void onError(ErrorInfo errorInfo) {
                if (playListener != null) {
                    playListener.onError(errorInfo);
                }
            }
        });
        aliPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
            @Override
            public void onCompletion() {
                if (playListener != null) {
                    playListener.onCompletion();
                }
            }
        });

        aliPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
            @Override
            public void onLoadingBegin() {
                if (playListener != null) {
                    playListener.onLoadingBegin();
                }
            }

            @Override
            public void onLoadingProgress(int i, float v) {
                if (playListener != null) {
                    playListener.onLoadingProgress(i, v);
                }
            }

            @Override
            public void onLoadingEnd() {
                if (playListener != null) {
                    playListener.onLoadingEnd();
                }
            }
        });

        aliPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
            @Override
            public void onStateChanged(int i) {
                 /*
                        int idle = 0;
                        int initalized = 1;
                        int prepared = 2;
                        int started = 3;
                        int paused = 4;
                        int stopped = 5;
                        int completion = 6;
                        int error = 7;
                */
                if (playListener != null) {
                    playListener.onStateChanged(i);
                }
            }
        });

        aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
            @Override
            public void onInfo(InfoBean infoBean) {
                if (playListener != null) {
                    playListener.onInfo(infoBean);
                }
                if (infoBean.getCode() == InfoCode.CurrentPosition) {
                    //extraValue为当前播放进度，单位为毫秒
                    playTime = infoBean.getExtraValue();
                }

            }
        });

        svPlay.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                aliPlayer.setSurface(holder.getSurface());
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
                aliPlayer.surfaceChanged();
            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                aliPlayer.setSurface(null);
            }
        });

        mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        // 最小值
        //        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        //            voiceMin = mAudioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
        //        }
        // 最大值
        voiceMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        pbVoice.setMax(voiceMax);

        if (getContext() instanceof Activity) {
            Log.e(TAG, "init: 获取到window");
            window = ((Activity) getContext()).getWindow();
            pbLight.setMax(100);
        }

        //        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    }

    /**
     * 设置播放器id 用于统计数据
     *
     * @param traceId IMEI 或 AndroidId
     */
    public void setTraceId(String traceId) {
        aliPlayer.setTraceId(traceId);
    }

    public String getVideoUrl() {
        return videoUrl;
    }

    public void setPlayTime(long playTime) {
        this.playTimeStart = playTime;
    }

    public void setVideoUrl(String videoUrl) {
        this.videoUrl = videoUrl;
        UrlSource urlSource = new UrlSource();
        urlSource.setUri(videoUrl);//播放地址，可以是第三方点播地址，或阿里云点播服务中的播放地址。
        aliPlayer.setDataSource(urlSource);
        aliPlayer.setAutoPlay(false);
        if (playTimeStart > 0) {
            aliPlayer.seekTo(playTimeStart);
        }
        aliPlayer.prepare();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        width = right - left;
        height = bottom - top;

    }

    /**
     * 获取当前系统亮度 百分比
     * 返回-1视为获取失败
     *
     * @return
     */
    public static double getSystemBrightness(Context context) {
        if (null != context) {
            try {
                double max = 255;
                Resources system = Resources.getSystem();
                int resId = system.getIdentifier("config_screenBrightnessSettingMaximum", "integer", "android");
                if (resId != 0) {
                    max = system.getInteger(resId);
                }
                return Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS) / max;
            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isLock) {
            return super.onTouchEvent(event);
        }
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                isHorizontal = false;
                isVertical = false;
                touchX = event.getX();
                touchY = event.getY();
                // 初始化
                isTouch = false;

                // 记录按下时播放时间
                playTimeDown = playTime;
                // 记录按下时音量
                VoiceCurrentDown = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                if (window != null) {
                    // 记录按下时亮度
                    brightnessDown = window.getAttributes().screenBrightness;
                    if (0 > brightnessDown) {
                        //                        Log.e(TAG, "onTouchEvent: 获取到系统亮度: " + getSystemBrightness(getContext()));
                        brightnessDown = (float) (getSystemBrightness(getContext()));
                    }
                    if (brightnessDown > 1) {
                        brightnessDown = 1;
                    }
                    //                    Log.e(TAG, "onTouchEvent: 获取到亮度: " + brightnessDown);
                } else {
                    //                    Log.e(TAG, "onTouchEvent: 获取亮度失败window为空");
                }

                if (touchY > height * 7 / 8d) {
                    return false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX() - touchX;
                float y = event.getY() - touchY;

                if (Math.abs(x) < 40 && Math.abs(y) < 40 && !isTouch) {
                    Log.e(TAG, "onTouchEvent: 取消:" + x + "  Y: " + y );
                    isTouch = true;
                    break;
                }


//                if (touchX < width / 5d || touchX > width * 4 / 5d) {
//                    if (!isHorizontal) {
//                        isVertical = true;
//                        changeVertical(event);
//                    }
//                } else
                    if (Math.abs(x) > Math.abs(y)) {
                    if (!isVertical) {
                        isHorizontal = true;
                        changeHorizontal(event);
                    }
                } else {
                    if (!isHorizontal) {
                        isVertical = true;
                        changeVertical(event);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isHorizontal) {
                    aliPlayer.seekTo(seekToNow);
                }
                isHorizontal = false;
                isVertical = false;
                tvTime.setVisibility(GONE);
                llLightBox.setVisibility(GONE);
                llVoiceBox.setVisibility(GONE);
                if (isHorizontal || isVertical) {
                    return true;
                }
                break;
        }

        return super.onTouchEvent(event);

    }

    /**
     * 横向滑动 改变播放时间
     *
     * @param event 手势
     */
    private void changeHorizontal(MotionEvent event) {
        tvTime.setVisibility(VISIBLE);
        float touchXNow = event.getX();
        float touchXMove = touchXNow - touchX;
        int seek = (int) (touchXMove * pxProgressValue) / 10;
        if (seek == 0) {
            seek = 1;
        }
        long seekTo = playTimeDown + seek;
        if (seekTo < 0) {
            seekTo = 0;
        }
        if (seekTo > maxProgressValue) {
            seekTo = maxProgressValue;
        }
        seekToNow = seekTo;
        Log.e(TAG, "changeVertical: 改变播放时间: " + seekTo);
        tvTime.setText(generateTime(seekTo));

        //        if (touchXMove > 0) {
        //            // 向右滑动   快进
        //            int seek = (int) (touchXMove * pxProgressValue);
        //            long seekTo = playTimeDown + seek;
        //
        //        }else{
        //            // 向左滑动   退后
        //        }
    }

    /**
     * 纵向滑动
     * View左边 改变亮度
     * View右边 改变音量
     *
     * @param event 手势
     */
    private void changeVertical(MotionEvent event) {
        float touchYNow = event.getY();

        // 滑动距离 取反
        float moveY = -(touchYNow - touchY);
        // 改变数据
        float changeNumber = moveY * 2 / height;
        if (touchX < width / 2d) {
            llLightBox.setVisibility(VISIBLE);
            // View左边 改变亮度
            float brightnessChange = brightnessDown + changeNumber;
            if (brightnessChange < 0) {
                brightnessChange = 0;
            }
            if (brightnessChange > 1) {
                brightnessChange = 1;
            }

            pbLight.setProgress((int) (brightnessChange * 100));

            WindowManager.LayoutParams attributes = window.getAttributes();
            attributes.screenBrightness = brightnessChange;
            window.setAttributes(attributes);
            Log.e(TAG, "changeVertical: 改变亮度: " + brightnessChange);
        } else {
            llVoiceBox.setVisibility(VISIBLE);
            // View右边 改变音量
            float voiceChange = VoiceCurrentDown + (changeNumber * voiceMax);
            if (voiceChange < 0) {
                voiceChange = 0;
            }
            if (voiceChange > voiceMax) {
                voiceChange = voiceMax;
            }
            Log.e(TAG, "changeVertical: 改变音量: " + voiceChange);
            pbVoice.setProgress((int) voiceChange);
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int) voiceChange, AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE); //音乐音量
        }

    }


    public void setPlayListener(PlayListener playListener) {
        this.playListener = playListener;
    }

    public AliPlayer getAliPlayer() {
        return aliPlayer;
    }


    /**
     * 将毫秒转时分秒
     *
     * @param time 毫秒值
     * @return 时分秒
     */
    public static String generateTime(long time) {
        int totalSeconds = (int) (time / 1000);
        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        if (hours > 0) {
            return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
        }
        if (minutes > 0) {
            return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
        }

        return String.format(Locale.getDefault(), "00:%02d", seconds);
    }

    public boolean isLock() {
        return isLock;
    }

    public void setLock(boolean lock) {
        isLock = lock;
    }

    public interface PlayListener {
        /**
         * 播放参数
         *
         * @param infoBean 播放参数
         */
        void onInfo(InfoBean infoBean);

        /**
         * 播放状态改变
         *
         * @param status 0:空闲
         *               1:初始化完成
         *               2:准备完成
         *               3:播放中
         *               4:暂停中
         *               5:已停止
         *               6:播放完成
         *               7:播放错误
         */
        void onStateChanged(int status);

        /**
         * 缓存相关 开始缓存
         */
        void onLoadingBegin();

        /**
         * 缓存相关 缓存进度
         *
         * @param progress 缓存进度
         * @param netSpeed 网速
         */
        void onLoadingProgress(int progress, float netSpeed);

        /**
         * 缓存相关 缓存结束
         */
        void onLoadingEnd();

        /**
         * 播放相关 加载完成,可以播放
         */
        void onPrepared();

        /**
         * 播放相关 加载失败
         *
         * @param errorInfo 失败信息
         */
        void onError(ErrorInfo errorInfo);

        /**
         * 播放相关 播放完成
         */
        void onCompletion();
    }

    /**
     * 播放进度改变
     */
    public interface OnProgressChangeListener {
        /**
         * 改变播放进度
         *
         * @param progress 进度
         */
        void changeProgress(long progress);

        /**
         * 播放进度手势处理
         *
         * @param progress 进度
         */
        void changeProgressHint(long progress);
    }
}
